#include "maininterface.h"
#include "ui_maininterface.h"
#include <QtCore>
#include <QtGui>

#include <newfilewindow.h>
#include <helpdialog.h>
#include <instructionsdialog.h>

#include <string>

using namespace std;
#define LINUX   //define LINUX for LINUX build and WINDOWS for windows build

#ifdef LINUX
#define SCRIPT "./rs274abc \""
#endif

#ifdef WINDOWS
    #define SCRIPT "Testrs274 \""
#endif

mainInterface::mainInterface(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::mainInterface)
{
    ui->setupUi(this);
    QIcon icon ;
    icon.addPixmap(QPixmap(":/Icon/Homebuild_cnc_colored.png"),QIcon::Disabled,QIcon::Off);


    this->setWindowIcon(icon);

    mOutFile = "out.txt";
    mGcodeFile = "in.txt";
    mToolFile = "rs274ngc.tool_default";
    mParamFile = "rs274ngc.var";

    ui->m_toolFilePlainTextEdit->setReadOnly(true);
    ui->m_parFilePlainTextEdit->setReadOnly(true);
    ui->m_outputLogPlainTextEdit->setReadOnly(true);

    QFile def_Gcode_File(mGcodeFile);
    QFile def_Tool_File(mToolFile);
    QFile def_Param_File(mParamFile);

    QString text;
    if(def_Gcode_File.open(QFile::ReadOnly | QFile::Text))
    {
        QTextStream in(&def_Gcode_File);
        while(!in.atEnd())
        {
            text = in.readLine();
            ui->m_inputGCodeListWidget->addItem(text);
        }
        def_Gcode_File.close();
    }
    else
        mGcodeFile = "";

    if(def_Tool_File.open(QFile::ReadOnly | QFile::Text))
    {
        QTextStream in(&def_Tool_File);

        text = in.readAll();
        ui->m_toolFilePlainTextEdit->appendPlainText(text);

        def_Tool_File.close();
    }
    else
        mToolFile = "";

    if(def_Param_File.open(QFile::ReadOnly | QFile::Text))
    {
        QTextStream in(&def_Param_File);

        text = in.readAll();
        ui->m_parFilePlainTextEdit->appendPlainText(text);

        def_Param_File.close();
    }
    else
        mParamFile = "";
}

mainInterface::~mainInterface()
{
    delete ui;
}

void mainInterface::on_actionNew_triggered()
{
    //New File
    m_newFilePtr = new newFileWindow(this);
    m_newFilePtr->show();
}

void mainInterface::on_actionSet_Output_Path_triggered()
{
    //Set output path
    QString file = QFileDialog::getOpenFileName(this,"Select Output Path");
    if(!file.isEmpty())
    {
        mOutFile = file;
    }
}

void mainInterface::on_actionView_Output_triggered()
{
    //View Output
    ui->m_outputLogPlainTextEdit->clear();
    QFile readOutFile(mOutFile);
    QString text;
    if(readOutFile.open(QFile::ReadOnly | QFile::Text))
    {
        QTextStream in(&readOutFile);
        text = in.readAll();
        ui->m_outputLogPlainTextEdit->appendPlainText(text);
    }
    else
        QMessageBox::information(this,"Output Error","No Output File");
    readOutFile.close();
}

void mainInterface::on_actionUpload_Output_triggered()
{
    //Upload
    QString uploadOutput = QFileDialog::getSaveFileName(this,"Upload Output File");
    if(!uploadOutput.isEmpty())
    {
        QFile readOutputFile(mOutFile);
        QFile uploadOutputFile(uploadOutput);
        if(readOutputFile.open(QFile::ReadOnly | QFile::Text))
        {
            if(uploadOutputFile.open(QFile::WriteOnly | QFile::Text))
            {
                QTextStream in(&readOutputFile);
                QTextStream out(&uploadOutputFile);
                QString text = in.readAll();
                out<<text;
            }

            readOutputFile.close();
            uploadOutputFile.close();
        }
        else
            QMessageBox::information(this,"Output Error","No Output File");
    }
}

void mainInterface::on_actionGCode_File_Open_triggered()
{
    //open Gcode File
    QString file = QFileDialog::getOpenFileName(this,"Open Gcode File");
    QString text;
    if(!file.isEmpty())
    {
        ui->m_inputGCodeListWidget->clear();
        QFile sFile(file);
        if(sFile.open(QFile::ReadOnly | QFile::Text))
        {
            mGcodeFile = file;
            QTextStream in(&sFile);
            while(!in.atEnd())
            {
                text = in.readLine();
                ui->m_inputGCodeListWidget->addItem(text);
            }
            sFile.close();
        }
    }
}

void mainInterface::on_actionTool_File_Open_triggered()
{
    //Open Tool File
    QString file = QFileDialog::getOpenFileName(this,"Open Tool File");
    QString text;
    if(!file.isEmpty())
    {
        ui->m_toolFilePlainTextEdit->clear();
        QFile sFile(file);
        if(sFile.open(QFile::ReadOnly | QFile::Text))
        {
            mToolFile = file;
            QTextStream in(&sFile);

            text = in.readAll();
            ui->m_toolFilePlainTextEdit->appendPlainText(text);

            sFile.close();
        }
    }
}

void mainInterface::on_actionParameter_File_Open_triggered()
{
    //Open Parameter File
    QString file = QFileDialog::getOpenFileName(this,"Open Parameter File");
    QString text;
    if(!file.isEmpty())
    {
        ui->m_parFilePlainTextEdit->clear();
        QFile sFile(file);
        if(sFile.open(QFile::ReadOnly | QFile::Text))
        {
            mParamFile = file;
            QTextStream in(&sFile);

            text = in.readAll();
            ui->m_parFilePlainTextEdit->appendPlainText(text);

            sFile.close();
        }
    }
}

void mainInterface::on_actionAbout_triggered()
{
    //About Dialog
    helpDialog help;
    help.setModal(false);
    help.exec();
}

void mainInterface::on_actionInstructions_triggered()
{
    //Instructions Dialog
    instructionsDialog inst;
    inst.setModal(false);
    inst.exec();
}

void mainInterface::on_m_useDefParamFile_clicked()
{
    //use default parameter file
    mParamFile = "rs274ngc.var";
    ui->m_parFilePlainTextEdit->clear();

    QFile def_Param_File(mParamFile);

    QString text;

    if(def_Param_File.open(QFile::ReadOnly | QFile::Text))
    {
        QTextStream in(&def_Param_File);

        text = in.readAll();
        ui->m_parFilePlainTextEdit->appendPlainText(text);

        def_Param_File.close();
    }
    else
    {
        mParamFile = "";
        QMessageBox::critical(this,"Input Error","Parameter File Not Found");
    }
}

void mainInterface::on_m_useDefToolFile_clicked()
{
    //use default tool file
    ui->m_toolFilePlainTextEdit->clear();
    mToolFile = "rs274ngc.tool_default";
    QFile def_Tool_File(mToolFile);

    QString text;

    if(def_Tool_File.open(QFile::ReadOnly | QFile::Text))
    {
        QTextStream in(&def_Tool_File);

        text = in.readAll();
        ui->m_toolFilePlainTextEdit->appendPlainText(text);

        def_Tool_File.close();
    }
    else
    {
        mToolFile = "";
        QMessageBox::critical(this,"Input Error","Tool File Not Found");
    }
}

void mainInterface::on_m_parseButton_clicked()
{
    //Parse
    ui->m_outputLogPlainTextEdit->clear();
    if(mGcodeFile.isEmpty())
        QMessageBox::critical(this,"Input File Error","GCode File Not selected");
    if(mToolFile.isEmpty())
        QMessageBox::critical(this,"Input File Error","Tool File Not selected");
    if(mParamFile.isEmpty())
        QMessageBox::critical(this,"Input File Error","Parameter File Not selected");

    QString text;

    if(mGcodeFile.length()!=0 && mToolFile.length()!=0 && mParamFile.length()!=0 && mOutFile.length()!=0)
    {
        string str(SCRIPT);
        str.append(mGcodeFile.toStdString());
        str.append("\"  \"");
        str.append(mOutFile.toStdString());
        str.append("\" \"");
        str.append(mToolFile.toStdString());
        str.append("\" \"");
        str.append(mParamFile.toStdString());
        str.append("\" \"");
        str.append("dummy\"");

        QFile checkGcodeFile(mGcodeFile);
        QFile checkToolFile(mToolFile);
        QFile checkParamFile(mParamFile);

        if(!checkParamFile.exists())
        {
            QMessageBox::critical(this,"Input Error","Parameter File Not Found");
            ui->m_outputLogPlainTextEdit->clear();
            ui->m_outputLogPlainTextEdit->appendPlainText("Input Error - Parameter File Not Found");
        }
        if(!checkToolFile.exists())
        {
            QMessageBox::critical(this,"Input Error","Tool File Not Found");
            ui->m_outputLogPlainTextEdit->clear();
            ui->m_outputLogPlainTextEdit->appendPlainText("Input Error - Tool File Not Found");
        }
        if(!checkGcodeFile.exists())
        {
            QMessageBox::critical(this,"Input Error","GCode File Not Found");
            ui->m_outputLogPlainTextEdit->clear();
            ui->m_outputLogPlainTextEdit->appendPlainText("Input Error - GCode File Not Found");
        }

        if(checkGcodeFile.exists())
        {
            if(checkToolFile.exists())
            {
                if(checkParamFile.exists())
                {
                    (void)system(str.c_str());
                    QFile readOutFile(mOutFile);
                    if(readOutFile.open(QFile::ReadOnly | QFile::Text))
                    {
                        QTextStream in(&readOutFile);
                        bool error = false;
                        while(!in.atEnd())
                        {
                            text = in.readLine();
                            if(text[0]=='@')
                            {
                                error = true;
                                ui->m_outputLogPlainTextEdit->appendPlainText(text);
                                text.remove(0,2);
                                text.chop(2);
                                QString itemData;
                                for (int i = 0; i < ui->m_inputGCodeListWidget->count(); i++)
                                {
                                    itemData = ui->m_inputGCodeListWidget->item(i)->text();
                                    while(itemData.endsWith(" "))
                                        itemData.chop(1);
                                    if(itemData.compare(text)==0)
                                    {
                                        ui->m_inputGCodeListWidget->setCurrentItem(ui->m_inputGCodeListWidget->item(i));
                                        ui->m_inputGCodeListWidget->item(i)->setBackgroundColor(Qt::red);
                                        break;
                                    }
                                }
                            }
                        }
                        if(error==true)
                            QMessageBox::information(this,"Error","Parsing Error");
                        else
                        {
                            QMessageBox::information(this,"Parse","Successfully Parsed");
                            ui->m_outputLogPlainTextEdit->clear();
                            ui->m_outputLogPlainTextEdit->appendPlainText("Sucsessfully parsed, to view the output File->View Output");
                        }
                        readOutFile.close();
                    }
                }
            }
        }
    }
}

void mainInterface::on_m_uploadButton_clicked()
{
    QString uploadOutput = QFileDialog::getSaveFileName(this,"Upload Output File");
    if(!uploadOutput.isEmpty())
    {
        QFile readOutputFile(mOutFile);
        QFile uploadOutputFile(uploadOutput);
        if(readOutputFile.open(QFile::ReadOnly | QFile::Text))
        {
            if(uploadOutputFile.open(QFile::WriteOnly | QFile::Text))
            {
                QTextStream in(&readOutputFile);
                QTextStream out(&uploadOutputFile);
                QString text = in.readAll();
                out<<text;
            }

            readOutputFile.close();
            uploadOutputFile.close();
        }
        else
            QMessageBox::information(this,"Output Error","No Output File");
    }
}
